<?php

namespace App\Http\Requests;

use Illuminate\Database\Query\Builder;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Validator;

class PhysicalStoreRequest extends FormRequest
{
    protected $physical;

    /**
     * Prepare the data for validation.
     * @return void
     */
    protected function prepareForValidation()
    {
        $this->physical = app('field')->get('physical');
    }

    /**
     * Determine if the user is authorized to make this request.
     * @return bool
     */
    public function authorize()
    {
        return \Auth::check();
    }

    //    public function withValidator(Validator $validator)
    //    {
    //        $validator->after(function (Validator $validator) {
    //            if ($validator->messages()->isEmpty()) {
    //
    //                if (is_null($bmi = $this->input('examination.bmi'))) {
    //                    return ;
    //                }
    //
    //                $stature = $this->input('examination.stature') / 100;
    //                $weight  = $this->input('examination.weight');
    //
    //                if ($bmi != round($weight / ($stature * $stature), 1)) {
    //                    $validator->errors()->add('examination.bmi', 'BMI 计算错误！');
    //                }
    //            }
    //        });
    //    }

    /**
     * Get the validation rules that apply to the request.
     * @return array
     */
    public function rules()
    {
        return [
            'record_id'                => [
                'required', 'integer', 'min:1',
                Rule::exists('st_medical_records', 'id')->where(function (Builder $query) {
                    $query->whereNull('deleted_at');
                    $user = \Auth::user();
                    if (!$user->isDoctorsAdmin() && !$user->isAdmin()) {
                        $query->where(['doctor_id' => $user->id]);
                    }
                }),
            ],
            'tongue'                   => 'nullable|array',
            'tongue.color'             => 'nullable|array',
            'tongue.color.*'           => 'in:' . implode(',', $this->physical['tongue']['color']),
            'tongue.status'            => 'nullable|array',
            'tongue.status.*'          => 'in:' . implode(',', $this->physical['tongue']['status']),
            'tongue.shape'             => 'nullable|array',
            'tongue.shape.*'           => 'in:' . implode(',', $this->physical['tongue']['shape']),
            'tongue.hypoglossis'       => 'nullable|array',
            'tongue.hypoglossis.*'     => 'in:' . implode(',', $this->physical['tongue']['hypoglossis']),
            'tongue.tongue_coating'    => 'nullable|array',
            'tongue.tongue_coating.*'  => 'in:' . implode(',', $this->physical['tongue']['tongue_coating']),
            'tongue.coating_color'     => 'nullable|array',
            'tongue.coating_color.*'   => 'in:' . implode(',', $this->physical['tongue']['coating_color']),
            'tongue.pulse_condition'   => 'nullable|array',
            'tongue.pulse_condition.*' => 'in:' . implode(',', $this->physical['tongue']['pulse_condition']),

            'examination.stature' => 'nullable|integer|min:0|max:999',
            'examination.weight'  => 'nullable|numeric|min:0|max:999|decimal:1',
            'examination.bmi'     => 'nullable|numeric|min:0',

            'examination.blood_pressure.low'  => 'nullable|required_with:examination.blood_pressure.high|integer|min:0|max:999',
            'examination.blood_pressure.high' => 'nullable|required_with:examination.blood_pressure.low|integer|min:0|max:999',
            'examination.pulse'               => 'nullable|integer|min:0|max:999',
            'examination.waistline'           => 'nullable|numeric|min:0|max:999|decimal:1',
            'examination.thyroid'             => 'nullable|in:' . implode(',',
                    $this->physical['examination']['thyroid']),
            'examination.edema'               => 'nullable|in:' . implode(',',
                    $this->physical['examination']['edema']),
            'examination.skin_rupture'        => 'nullable|in:' . implode(',',
                    $this->physical['examination']['skin_rupture']),
            'examination.large_limb_profile'  => 'nullable|in:' . implode(',',
                    $this->physical['examination']['large_limb_profile']),

            'cn_examination.heart_rate'             => 'nullable|integer|min:1|max:250',
            'cn_examination.heart_rhythm'           => 'nullable|max:50',
            'cn_examination.heart_sound'            => 'nullable|max:50',
            'cn_examination.liver_spleen_palpation' => 'nullable|max:50',
            'cn_examination.thorax'                 => 'nullable|max:50',
            'cn_examination.lung_respiratory_sound' => 'nullable|max:50',
            'cn_examination.rale'                   => 'nullable|max:50',
            'cn_examination.abdominal_mass'         => 'nullable|in:0,1',
            'cn_examination.liver_area_percussion'  => 'nullable|max:50',
            'cn_examination.renal_area_percussion'  => 'nullable|max:50',

            'other.sfp'                   => 'nullable|in:0,1,2',
            'other.buffalo_hump'          => 'nullable|in:0,1,2',
            'other.acanthosis_nigricans'  => 'nullable|in:0,1,2',
            'other.ecchymosis'            => 'nullable|in:0,1,2',
            'other.apl'                   => 'nullable|in:0,1,2',
            'other.pericardial_fricative' => 'nullable|in:0,1,2',
            'other.pleural_fricative'     => 'nullable|in:0,1,2',
            'other.murphy_character'      => 'nullable|in:0,1,2',
            'other.moving_dullness'       => 'nullable|in:0,1,2',
            'other.ankle_reflex'          => 'nullable|in:1,2',
            'other.btnp'                  => 'nullable|in:1,2',
            'other.bttfvs'                => 'nullable|in:1,2',
            'other.10gnt'                 => 'nullable|in:1,2',

            'remark' => 'nullable|string|max:255',
        ];
    }

    public function messages()
    {
        return [
            'record_id.required' => '缺少病历ID',
            'record_id.integer'  => '病历ID 必须是整数。',
            'record_id.min'      => '病历ID 必须大于等于 :min。',
            'record_id.exists'   => '病历 不存在或无修改该病历的权限。',

            'remark.max' => '备注最大 :max 个字符',
        ];
    }
}
